﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using CompleteReader.Common;

using CompleteReader.Dialogs;
using CompleteReader.Flyouts;
using Windows.Storage;
using pdftron.PDF;
using CompleteReader.Utilities;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace CompleteReader
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class ViewerPage : Windows.UI.Xaml.Controls.Page
    {
        public static ViewerPage Current;

        private NavigationHelper _NavigationHelper;
        private StorageFile PDFFile;
        private PDFViewCtrl PDFViewCtrl;
        private Windows.Storage.Streams.IRandomAccessStream Stream;
        private pdftron.PDF.Tools.ToolManager ToolManager;

        private Utilities.SharingHelper _SharingHelper;
        private pdftron.PDF.PDFPrintManager _PDFPrintManager;

        private DispatcherTimer _AppBarClosingTimer;

        private AppBar _ThumbSliderAppBar;
        private CommandBar _TopAppBar;

        //private Utilities.AutoSaveHelper _AutoSaveHelper;

        private pdftron.PDF.Tools.Controls.ThumbnailViewer _ThumbnailViewer;

        private bool _IsReadOnly = false;

        public ViewerPage()
        {
            this.InitializeComponent();
            this._NavigationHelper = new NavigationHelper(this);


            this.PDFViewCtrl = new PDFViewCtrl();
            PDFViewCtrlBorder.Child = this.PDFViewCtrl;

            this.PDFViewCtrl.SetZoomLimits(ZoomLimitMode.e_zoom_limit_relative, 1, 20); // Double size 3 times.
            this.PDFViewCtrl.SetBackgroundColor(Windows.UI.Color.FromArgb(255, 40, 40, 40));

            this.PDFViewCtrl.SetProgressiveRendering(true);
            this.PDFViewCtrl.SetPageRefViewMode(PDFViewCtrlPageViewMode.e_fit_page);
            this.PDFViewCtrl.SetPageViewMode(this.PDFViewCtrl.GetPageRefViewMode());
            this.PDFViewCtrl.SetupThumbnails(false, true, true, 500, 100 * 1024 * 1024, 0.1);
            this.PDFViewCtrl.SetBackgroundColor(Windows.UI.Color.FromArgb(255, 100, 100, 100));
            
            this.Loaded += ViewerPage_Loaded;


            this.ToolManager = new pdftron.PDF.Tools.ToolManager(this.PDFViewCtrl);
            this.ToolManager.EnablePopupMenuOnLongPress = true;
            this.ToolManager.UseSmallPageNumberIndicator = false;
            this.ToolManager.AuthorDialog = this.AuthorDialog;
            PageNumberBorder.Child = this.ToolManager.PageNumberIndicator;

            OutlineDialog.PDFViewCtrl = this.PDFViewCtrl;
            QuickSettings.PDFViewCtrl = this.PDFViewCtrl;
            AnnotationToolbarDialog.ToolManager = this.ToolManager;            
            FindTextDialog.PDFViewCtrl = this.PDFViewCtrl;

            _AppBarClosingTimer = new DispatcherTimer();
            _AppBarClosingTimer.Interval = TimeSpan.FromSeconds(5);
            _AppBarClosingTimer.Tick += AppBarClosingTimer_Tick;

            this.ThumbnailSlider.ManipulationStarted += ThumbnailSlider_ManipulationStarted;
            this.ThumbnailSlider.ManipulationCompleted += ThumbnailSlider_ManipulationCompleted;
            this.ThumbnailSlider.AddHandler(PointerPressedEvent, new PointerEventHandler(ThumbnailSlider_PointerPressed), true);
            this.ThumbnailSlider.PointerReleased += ThumbnailSlider_PointerReleased;

            SetPagePresentationMode();
            SetNightMode();
        }


        void ViewerPage_Loaded(object sender, RoutedEventArgs e)
        {
            _ThumbSliderAppBar = this.BottomAppBar;
            _TopAppBar = this.TopAppBar as CommandBar;
        }



        /// <summary>
        /// Populates the page with content passed during navigation. Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="sender">
        /// The source of the event; typically <see cref="NavigationHelper"/>
        /// </param>
        /// <param name="e">Event data that provides both the navigation parameter passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested and
        /// a dictionary of state preserved by this page during an earlier
        /// session. The state will be null the first time a page is visited.</param>
        private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
        {
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="sender">The source of the event; typically <see cref="NavigationHelper"/></param>
        /// <param name="e">Event data that provides an empty dictionary to be populated with
        /// serializable state.</param>
        private void navigationHelper_SaveState(object sender, SaveStateEventArgs e)
        {
        }

        #region NavigationHelper registration

        /// The methods provided in this section are simply used to allow
        /// NavigationHelper to respond to the page's navigation methods.
        /// 
        /// Page specific logic should be placed in event handlers for the  
        /// <see cref="GridCS.Common.NavigationHelper.LoadState"/>
        /// and <see cref="GridCS.Common.NavigationHelper.SaveState"/>.
        /// The navigation parameter is available in the LoadState method 
        /// in addition to page state preserved during an earlier session.

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            _NavigationHelper.OnNavigatedTo(e);

            this.QuickSettings.PresentationModeChanged += QuickSettings_PresentationModeChanged;
            this.QuickSettings.NightModeChanged += QuickSettings_NightModeChanged;
            this.QuickSettings.RotateClockwiseRequested += QuickSettings_RotateClockwiseRequested;
            this.QuickSettings.ThumbnailViewRequested += QuickSettings_ThumbnailViewRequested;
            this.PDFViewCtrl.KeyDown += PDFViewCtrl_KeyDown;
            this.PDFViewCtrl.IsEnabledChanged += PDFViewCtrl_IsEnabledChanged;

            // printing
            _PDFPrintManager = PDFPrintManager.GetInstance();

            Windows.ApplicationModel.Resources.ResourceLoader loader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView("Printing");
                //new Windows.ApplicationModel.Resources.ResourceLoader();
            _PDFPrintManager.SetResourceLoader(loader);

            // standard options
            _PDFPrintManager.AddStandardPrintOption(Windows.Graphics.Printing.StandardPrintTaskOptions.MediaSize);
            _PDFPrintManager.AddStandardPrintOption(Windows.Graphics.Printing.StandardPrintTaskOptions.Orientation);

            // PDFTron options
            _PDFPrintManager.AddUserOptionAnnotations();
            _PDFPrintManager.AddUserOptionAutoRotate();
            _PDFPrintManager.AddUserOptionPageRange();


            // handle the document
            Data.NavigationParameter param = e.Parameter as Data.NavigationParameter;
            if (param != null)
            {
                this.PDFViewCtrl.SetDoc(param.Doc);
                this.PDFFile = param.File;
                this.Stream = param.Stream;

                if (param.ReadOnly)
                {
                    _IsReadOnly = true;
                    AppBarButton_Save.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                }
                else
                {
                    // This will automatically save the document every 30 seconds, provided it has been modified.
                    //_AutoSaveHelper = new Utilities.AutoSaveHelper(30);
                    //_AutoSaveHelper.PDFDoc = param.Doc;
                }

                _SharingHelper = Utilities.SharingHelper.GetSharingHelper();
                _SharingHelper.RetrieveSharingStorageFile += SharingHelper_RetrieveSharingStorageFile;

                AddAnalytics(param);

                if (param.Doc.GetPageCount() > 4)
                {
                    this.ThumbnailSlider.PDFViewCtrl = this.PDFViewCtrl;
                }
                else
                {
                    this.BottomAppBar = null;
                    _ThumbSliderAppBar = null;
                }

                // register document for printing
                string docTitle = "Untitled";
                try
                {
                    docTitle = param.Doc.GetDocInfo().GetTitle();
                }
                catch (Exception)
                {
                    // no need to do anything, it just means that the document doesn't have a title
                }
                _PDFPrintManager.RegisterForPrintingContract(param.Doc, docTitle);
            }
        }

        private async void AddAnalytics(Data.NavigationParameter param)
        {
            AnalyticsHandler.CURRENT.AddCrashExtraData("PDFDoc Page Count", param.Doc.GetPageCount().ToString());
            if (param.File != null)
            {
                ulong size = await AnalyticsHandler.CURRENT.GetFileSizeAsync(param.File);
                AnalyticsHandler.CURRENT.AddCrashExtraData("File size in byte", size.ToString());
            }
            else
            {
                AnalyticsHandler.CURRENT.AddCrashExtraData("File size in byte", "No file. Read Only");
            }
        }

        StorageFile SharingHelper_RetrieveSharingStorageFile()
        {
            return PDFFile;
        }


        /// <summary>
        /// When we navigate away from this page, the ToolManager and the PDFDoc should be destroyed
        /// Also, we must unsubscribe to any event we have previously subscribed to on the PDFViewCtrl.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            //if (_AutoSaveHelper != null)
            //{
            //    _AutoSaveHelper.Stop();
            //}
            CloseDoc();
            _NavigationHelper.OnNavigatedFrom(e);
            this.ToolManager.Dispose();

            this.QuickSettings.PresentationModeChanged -= QuickSettings_PresentationModeChanged;
            this.QuickSettings.NightModeChanged -= QuickSettings_NightModeChanged;
            this.QuickSettings.RotateClockwiseRequested -= QuickSettings_RotateClockwiseRequested;
            this.QuickSettings.ThumbnailViewRequested -= QuickSettings_ThumbnailViewRequested;
            this.PDFViewCtrl.KeyDown -= PDFViewCtrl_KeyDown;
            this.PDFViewCtrl.IsEnabledChanged -= PDFViewCtrl_IsEnabledChanged;
            //this.PDFViewCtrl.OnSetDoc -= PDFViewCtrl_OnSetDoc;

            if (_ThumbSliderAppBar != null)
            {
                _ThumbSliderAppBar.Content = null;
            }

            _SharingHelper.RetrieveSharingStorageFile -= SharingHelper_RetrieveSharingStorageFile;
            _AppBarClosingTimer.Stop();

            _PDFPrintManager.UnRegisterForPrintingContract();
        }

        void PDFViewCtrl_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (((bool)e.NewValue) == true)
            {
                AttachAppBars();
                this.AnnotationToolbarDialog.IsEnabled = true;
                this.FindTextDialog.IsEnabled = true;
            }
            else
            {
                this.AnnotationToolbarDialog.IsEnabled = false;
                this.FindTextDialog.IsEnabled = false;
                DetachAppBars();
            }
        }

        /// <summary>
        /// Closes the document and then disposes of it in a background thread.
        /// </summary>
        private async void CloseDoc()
        {
            PDFDoc doc = this.PDFViewCtrl.GetDoc();

            this.PDFViewCtrl.CloseDoc();
            

            if (doc != null)
            {
                await CloseDocAsync(doc);
            }

            this.PDFViewCtrl.FreeResources();
            //this.PDFViewCtrl.Dispose();
        }

        private IAsyncAction CloseDocAsync(PDFDoc doc)
        {
            System.Threading.Tasks.Task t = new System.Threading.Tasks.Task(() =>
            {
                doc.Dispose();
            });
            t.Start();
            return t.AsAsyncAction();
        }


        #endregion NavigationHelper registration

        #region AppBar
        private void DetachAppBars()
        {
            this.TopAppBar = null;
            this.BottomAppBar = null;
        }

        private void AttachAppBars()
        {
            if (this.TopAppBar == null)
            {
                this.TopAppBar = _TopAppBar;
            }
            if (this.BottomAppBar == null)
            {
                this.BottomAppBar = _ThumbSliderAppBar;
            }
        }



        private async void FileAppBarButton_Clicked(object sender, RoutedEventArgs e)
        {
            AnalyticsHandler.CURRENT.SendEvent("[File Browser] RecentListView opened");
            this.FindTextDialog.CloseDialog();

            Windows.ApplicationModel.Resources.ResourceLoader loader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

            if (_IsReadOnly)
            {
                if (IsModified())
                {
                    Windows.UI.Popups.MessageDialog messageDialog = new Windows.UI.Popups.MessageDialog(loader.GetString("SaveBeforeClosingDialog_Info"), loader.GetString("SaveBeforeClosingDialog_Title"));
                    messageDialog.Commands.Add(new Windows.UI.Popups.UICommand(loader.GetString("SaveBeforeClosingDialog_Save_Option"), (command) =>
                    {
                        // We can't call SaveAs(true) here, or we'll get an UnauthorizedAccessException when trying to open the file picker.
                        DelaySaveAs();
                    }));
                    messageDialog.Commands.Add(new Windows.UI.Popups.UICommand(loader.GetString("SaveBeforeClosingDialog_Discard_Option"), (command) =>
                    {
                        GoToFilePage();
                    }));
                    messageDialog.Commands.Add(new Windows.UI.Popups.UICommand(loader.GetString("SaveBeforeClosingDialog_Cancel_Option"), (command) =>
                    {
                    }));
                    await Utilities.MessageDialogHelper.ShowMessageDialogAsync(messageDialog);
                }
                else
                {
                    GoToFilePage();
                }
            }
            else
            {
                Save();
                GoToFilePage();
            }

        }

        private async void DelaySaveAs()
        {
            // We wait a little, and the save picker can safely be open.
            await System.Threading.Tasks.Task.Delay(100);
            SaveAs(true);
        }

        private void GoToFilePage()
        {
            if (this.Frame.CanGoBack)
            {
                this.Frame.GoBack();
            }
            else
            {
                this.Frame.Navigate(typeof(DocumentsPage));
            }
        }

        private void EditAppBarButton_Clicked(object sender, RoutedEventArgs e)
        {
            this.AnnotationToolbarDialog.OpenDialog();
            CloseAppBars();
            AppbarInteraction();
            AnalyticsHandler.CURRENT.SendEvent("[Annotation Toolbar] Annotation Toolbar opened");
        }

        private void SearchAppBarButton_Clicked(object sender, RoutedEventArgs e)
        {
            this.FindTextDialog.OpenDialog();
            CloseAppBars();
            AppbarInteraction();
            AnalyticsHandler.CURRENT.SendEvent("[Viewer] Find Text clicked");
        }

        private void OutlineAppBarButton_Clicked(object sender, RoutedEventArgs e)
        {
            this.OutlineDialog.OpenDialog();
            CloseAppBars();
            FlyoutDialogEnabled();
        }


        private void TopAppBar_Opened(object sender, object e)
        {           
            this.FindTextDialog.CloseDialog();
            this.OutlineDialog.CloseDialog();
            CloseThumbnailsViewer();
            AppbarInteraction();
        }

        private void TopAppBar_Closed(object sender, object e)
        {

        }

        private void CloseAppBars()
        {
            if (this.BottomAppBar != null)
            {
                this.BottomAppBar.IsOpen = false;
            }
            if (this.TopAppBar != null)
            {
                this.TopAppBar.IsOpen = false;
            }
            _AppBarClosingTimer.Stop();
        }


        private void SaveAppBarButton_Clicked(object sender, RoutedEventArgs e)
        {
            AnalyticsHandler.CURRENT.SendEvent("[Viewer] save button pressed");

            AppbarInteraction();
            Save();
        }

        private void SaveAsAppBarButton_Click(object sender, RoutedEventArgs e)
        {
            AnalyticsHandler.CURRENT.SendEvent("[Viewer] save as button pressed");

            AppbarInteraction();
            SaveAs();
        }

        // Auto closing the app bar
        private void AppbarInteraction()
        {
            this._AppBarClosingTimer.Stop();
            this._AppBarClosingTimer.Start();
        }


        private void AppBarClosingTimer_Tick(object sender, object e)
        {
            CloseAppBars();
            DispatcherTimer timer = sender as DispatcherTimer;
            timer.Stop();
        }


        ////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // These listeners lets us know when not to clsoe the app bar automatically.

        void ThumbnailSlider_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
            _AppBarClosingTimer.Start();
        }

        private void ThumbnailSlider_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
        {
            _AppBarClosingTimer.Stop();
        }

        void ThumbnailSlider_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            _AppBarClosingTimer.Stop();
        }

        void ThumbnailSlider_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            _AppBarClosingTimer.Start();
        }

        private void ViewModeFlyout_Opening(object sender, object e)
        {
        }

        private void ViewModeFlyout_Closed(object sender, object e)
        {
        }

        #endregion AppBar


        #region FlyoutManagement
        private void FlyoutDialogEnabled()
        {
            TapOverlayGrid.Visibility = Windows.UI.Xaml.Visibility.Visible;
        }

        private void FlyoutDialogDisabled()
        {
            TapOverlayGrid.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            this.OutlineDialog.CloseDialog();
        }

        private void TapOverlayGrid_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            FlyoutDialogDisabled();
        }

        #endregion FlyoutManagement


        #region Settings
        private void QuickSettings_PresentationModeChanged()
        {
            SetPagePresentationMode();
        }

        private void SetPagePresentationMode()
        {
            CloseAppBars();
            PDFViewCtrlPagePresentationMode oldPresentationMode = this.PDFViewCtrl.GetPagePresentationMode();
            PDFViewCtrlPageViewMode oldViewMode = this.PDFViewCtrl.GetPageViewMode();
            this.PDFViewCtrl.SetPagePresentationMode(Settings.Settings.PagePresentationMode);
            AnalyticsHandler.CURRENT.SendEvent("[Viewer] Presentation mode selected: " + Settings.Settings.PagePresentationMode.ToString());
        }

        public void SetButtonsStayDown(bool stayDown)
        {
            AnnotationToolbarDialog.ButtonsStayDown = stayDown;

            AnalyticsHandler.CURRENT.SendEvent("[General] Continuous Annotation Edit enabled");
        }

        private void QuickSettings_NightModeChanged()
        {
            CloseAppBars();
            SetNightMode();
        }

        private void SetNightMode()
        {
            if (Settings.Settings.NightMode)
            {
                this.PDFViewCtrl.SetColorPostProcessMode(PDFRasterizerColorPostProcessMode.e_postprocess_invert);
                this.PDFViewCtrl.Update(true);
            }
            else
            {
                this.PDFViewCtrl.SetColorPostProcessMode(PDFRasterizerColorPostProcessMode.e_postprocess_none);
                this.PDFViewCtrl.Update(true);
            }
        }


        void QuickSettings_RotateClockwiseRequested()
        {
            this.PDFViewCtrl.RotateClockwise();
            AppbarInteraction();
        }


        void QuickSettings_ThumbnailViewRequested()
        {
            CloseAppBars();
            ThumbnailViewGrid.Visibility = Windows.UI.Xaml.Visibility.Visible;
            this.PDFViewCtrl.IsEnabled = false;
            _ThumbnailViewer = new pdftron.PDF.Tools.Controls.ThumbnailViewer(this.PDFViewCtrl);
            if (Settings.Settings.NightMode)
            {
                ThumbnailViewGrid.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 50, 50, 50));
                _ThumbnailViewer.BlankPageDefaultColor = Windows.UI.Colors.Black;
            }
            else
            {
                ThumbnailViewGrid.Background = new SolidColorBrush(Windows.UI.Colors.Black);
            }
            _ThumbnailViewer.ControlClosed += ThumbnailsViewer_ControlClosed;
            ThumbnailViewGrid.Children.Add(_ThumbnailViewer);
        }

        void ThumbnailsViewer_ControlClosed()
        {
            CloseThumbnailsViewer();
        }

        private void CloseThumbnailsViewer()
        {
            ThumbnailViewGrid.Children.Clear();
            ThumbnailViewGrid.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            this.PDFViewCtrl.IsEnabled = true;
            if (_ThumbnailViewer != null)
            {
                _ThumbnailViewer.ControlClosed -= ThumbnailsViewer_ControlClosed;
            }
        }

        #endregion Settings

        private void PDFViewCtrl_KeyDown(object sender, KeyRoutedEventArgs e)
        {
            Windows.UI.Core.CoreVirtualKeyStates state = Windows.UI.Core.CoreWindow.GetForCurrentThread().GetKeyState(Windows.System.VirtualKey.Control);
            if ((state & Windows.UI.Core.CoreVirtualKeyStates.Down) == Windows.UI.Core.CoreVirtualKeyStates.Down)
            {
                switch (e.Key)
                {
                    case Windows.System.VirtualKey.F:
                        this.FindTextDialog.OpenDialog();
                        break;
                }
            }
        }

        private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            this.PDFViewCtrl.Width = e.NewSize.Width;
            this.PDFViewCtrl.Height = e.NewSize.Height;
            SetPagePresentationMode();
        }

        #region Saving


        private bool IsModified()
        {
            bool isModified = false;
            try
            {
                this.PDFViewCtrl.DocLock(true);
                PDFDoc doc = this.PDFViewCtrl.GetDoc();
                if (doc != null && doc.IsModified())
                {
                    isModified = true;
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("Error when checking if modified: " + e.Message);
            }
            finally
            {
                this.PDFViewCtrl.DocUnlock();
            }
            return isModified;
        }



        async void Save()
        {
            pdftron.PDF.PDFDoc doc = this.PDFViewCtrl.GetDoc();
            if (doc == null)
            {
                return;
            }

            bool success = false;
            bool locked = false;
            try
            {
                this.PDFViewCtrl.DocLockRead();
                locked = true;
                if (doc.IsModified())
                {
                    this.PDFViewCtrl.DocUnlockRead();
                    locked = false;
                    await doc.SaveAsync(pdftron.SDF.SDFDocSaveOptions.e_incremental);
                }
                success = true;
            }
            catch (Exception)
            {
                success = false;
            }
            finally
            {
                if (locked)
                {
                    this.PDFViewCtrl.DocUnlockRead();
                }
            }
            if (!success)
            {
                Windows.UI.Popups.MessageDialog msg = new Windows.UI.Popups.MessageDialog("Could not save file. Ensure that the file is not used by another program.");
                await Utilities.MessageDialogHelper.ShowMessageDialogAsync(msg);
            }
        }


        public async void SaveAs(bool closeIfsuccessful = false)
        {
            PDFDoc doc = this.PDFViewCtrl.GetDoc();
            if (doc == null)
            {
                return;
            }



            Windows.Storage.Pickers.FileSavePicker fileSavePicker = new Windows.Storage.Pickers.FileSavePicker();
            fileSavePicker.CommitButtonText = "Save";
            fileSavePicker.FileTypeChoices.Add("PDF Document", new List<string>() { ".pdf" });
            StorageFile file = await fileSavePicker.PickSaveFileAsync();

            if (file != null)
            {
                bool success = false;
                bool locked = false;
                SaveAsNotification san = new SaveAsNotification();
                DateTime saveTime = DateTime.Now;
                int millisecondsToWait = 0;

                try
                {
                  
                    ControlDisplayGrid.Children.Add(san);
                    this.PDFViewCtrl.IsEnabled = false;

                    await doc.SaveAsync(file, pdftron.SDF.SDFDocSaveOptions.e_incremental);
                    this.PDFFile = file;
                    success = true;

                    this.PDFViewCtrl.DocLockRead();
                    locked = true;
                    bool isEncrypted = !doc.InitStdSecurityHandler("");
                    Data.RecentItemsData recentItems = await Data.RecentItemsData.GetItemSourceAsync(this);
                    recentItems.UpdateWithNewFile(this.PDFFile, isEncrypted);
                    if (!isEncrypted)
                    {
                        pdftron.Common.RecentlyUsedCache.AccessDocument(this.PDFFile.Path);
                    }

                }
                catch (Exception)
                {
                    success = false;
                }
                finally
                {
                    if (locked)
                    {
                        this.PDFViewCtrl.DocUnlockRead();
                    }
                    TimeSpan timeLeftToWait = TimeSpan.FromSeconds(1) - (DateTime.Now - saveTime);
                    millisecondsToWait = (int)timeLeftToWait.TotalMilliseconds;
                   
                }

                if (millisecondsToWait > 0)
                {
                    await System.Threading.Tasks.Task.Delay(millisecondsToWait);
                }

                ControlDisplayGrid.Children.Remove(san);
                this.PDFViewCtrl.IsEnabled = true;
 
                if (success)
                {
                    if (closeIfsuccessful)
                    {
                        GoToFilePage();
                        return;
                    }

                    // in case we were looking at a read only document.
                    AppBarButton_Save.Visibility = Windows.UI.Xaml.Visibility.Visible;
                    //if (_AutoSaveHelper == null)
                    //{
                    //    AppBarButton_Save.Visibility = Windows.UI.Xaml.Visibility.Visible;

                    //    // This will automatically save the document every 30 seconds, provided it has been modified.
                    //    _AutoSaveHelper = new Utilities.AutoSaveHelper(30);
                    //    _AutoSaveHelper.PDFDoc = doc;
                    //    _IsReadOnly = false;
                    //}
                    //else
                    //{
                    //    _AutoSaveHelper.Stop();
                    //    _AutoSaveHelper.Start();
                    //}
                }
                else
                {
                    Windows.UI.Popups.MessageDialog msg = new Windows.UI.Popups.MessageDialog("The file could not be saved.");
                }
            }
        }
        #endregion Saving
    }
}
